#ifndef INSTANCE_BACKLOG_ECHELON_H
#define INSTANCE_BACKLOG_ECHELON_H

/*	CLASS:		InstanceBacklogEchelon
	AUTHOR:		Marcelo Y. B. Hossomi

	Contains instance specific data with backlogging, using the
	echelon reformulation.
*/

#include "Instance.h"
#include "Input.h"

class InstanceBacklogEchelon: public Instance {
private:

	double		*capacityCost;		// J x M
	double		*setupCost;			// J
	double		*backlogCost;		// J
	double		*upperBound;		// J x T
	double		*totalCapacity;		// M x T
	double		*demand;			// J x T
	double		*holdingCost;		// J
	double		*resourceCost;		// J x T
	double		*setupTime;			// M x J

	double		*eholdingCost;		// J (echelon holding cost)
	double		*edemand;			// J x T (echelon demand)
	double		*lsdemand;			// J x T x T (ls demand)

	int			*endProducts;		// Je (index of end products)
	int			**successor;		// J x ? (list of successors of product j)
	int			*successorCount;	// J (number of successors of product j)
	bool		flagFinalBacklog;

	double calcEchelonDemand( int j, int t );
	double calcTotalEchelonDemand( int j, int t );

public:

	// Initializes all fields.
	InstanceBacklogEchelon();

	// Cleans all allocated memory.
	~InstanceBacklogEchelon();

	// Loads an instance.
	bool load( const char *name );

	// Returns the instance full path.
	char* getPath( const char *name );

	// Returns the solution size.
	int getSolutionSize();
	//int getSolutionRows();

	// Prints this instance data.
	void print();

	// Returns instance data.
	double getCapacityCost( int m, int j );
	double getUpperBound( int j, int t );
	double getSetupCost( int j );
	double getBacklogCost( int j );
	double getTotalCapacity( int m, int t );
	double getDemand( int j, int t );
	double getHoldingCost( int j );
	double getResourceCost( int j, int k );
	double getSetupTime( int m, int j );
	int getEndProduct( int i );
	int getSuccessor( int j, int i );
	int getSuccessorCount( int j );
	bool isEndProduct( int j );
	bool allowFinalBacklog();

	double getEchelonHoldingCost( int j );
	double getEchelonDemand( int j, int t );
	double getLSDemand( int j, int l, int t );
};

#endif